/**
 * Siglaz Namespace
 * 
 * @namespace
 */

var Siglaz = {};

// /////////////////////////////////////////////////////////////////////
// Siglaz.Shape
// /////////////////////////////////////////////////////////////////////

Siglaz.Shape = function() {
	this._graphicType = "Shape";
	this._attrs = {};
	this._options = {
		matrix : [ 1, 0, 0, 1, 0, 0 ],
		rotate: 0,
		stroke : {
			"color" : "black",
			"width" : 1
		},
		fill : null,
		visible : true,
		selected : false,
		selectable : true
	};
	this._check = {
		mouse_on: false
	};
	this._eventListeners = {};
};

Siglaz.Shape.prototype = {
	_checkSelected: function(iContain, graphic){
		if(this.isSelectable() && iContain == true && this.isSelected() == false)
		{
			this._options.selected = true;
			graphic.drawSelectedObject();
		}
		else if(iContain == false && this.isSelected() == true)
		{
			this._options.selected = false;
			graphic.drawSelectedObject();
		}
	},
	_onEvent: function(e, x, y, graphic){
		var type = e.type;
		var iContain = this.containsPoint(x, y);
		
		if(type == "click" || type == "mouseup")
			this._checkSelected(iContain, graphic);
		
		if(iContain == false && this._check.mouse_on == false)
			return;
		
		if(type == "mousemove"){
			if(iContain == true){
				if(this._check.mouse_on == false){
					this._check.mouse_on = true;
					this._onMouseOver(e);
				}
				else{
					this._onMouseMove(e);
				}
			}
			else{
				if(this._check.mouse_on == true){
					this._check.mouse_on = false;
					this._onMouseOut(e);
				}
			}
		}
		else {
			switch(type){
				case "click":
					this._onClick(e);
					break;
				case "mousedown":
					this._onMouseDown(e);
					break;
				case "mouseup":
					this._onMouseUp(e);
					break;
				default:
					break;
			}
		}
	},
	_onMouseOver: function(e){
		this._handleEvents("mouseover", e);
	},
	_onMouseMove: function(e){
		this._handleEvents("mousemove", e);
	},
	_onClick: function(e){
		this._handleEvents("click", e);
	},
	_onMouseOut: function(e){
		this._handleEvents("mouseout", e);
	},
	_onMouseDown: function(e){
		this._handleEvents("mousedown", e);
	},
	_onMouseUp: function(e){
		this._handleEvents("mouseup", e);
	},
	_handleEvents: function(eventType, e){
		var el = this._eventListeners;
		if(el[eventType]) {
            var events = el[eventType];
            for(var i = 0; i < events.length; i++) {
                events[i].handler.apply(this, e);
            }
        }
	},
	on: function(typesStr, handler){
		var types = typesStr.split(' ');
		/*
         * loop through types and attach event listeners to
         * each one.  eg. 'click mouseover.namespace mouseout'
         * will create three event bindings
         */
        for(var n = 0; n < types.length; n++) {
            var type = types[n];
            var parts = type.split('.');
            var baseEvent = parts[0];
            var name = parts.length > 1 ? parts[1] : '';

            if(!this._eventListeners[baseEvent]) {
                this._eventListeners[baseEvent] = [];
            }

            this._eventListeners[baseEvent].push({
                name: name,
                handler: handler
            });
        }
	},
	off: function(typesStr) {
        var types = typesStr.split(' ');

        for(var n = 0; n < types.length; n++) {
            var type = types[n];
            var parts = type.split('.');
            var baseEvent = parts[0];

            if(this._eventListeners[baseEvent] && parts.length > 1) {
                var name = parts[1];

                for(var i = 0; i < this._eventListeners[baseEvent].length; i++) {
                    if(this._eventListeners[baseEvent][i].name === name) {
                        this._eventListeners[baseEvent].splice(i, 1);
                        if(this._eventListeners[baseEvent].length === 0) {
                            this._eventListeners[baseEvent] = undefined;
                        }
                        break;
                    }
                }
            }
            else {
                this._eventListeners[baseEvent] = undefined;
            }
        }
    },
	isVisible : function() {
		return this._options.visible;
	},
	isSelected : function() {
		return this._options.selected;
	},
	isSelectable : function() {
		return this._options.selectable;
	},
	/**
	 * Set visible
	 * 
	 * @param: {Bool} visible
	 */
	setVisible : function(visible) {
		this._options.visible = visible;
	},
	/**
	 * Set selected
	 * 
	 * @param: {Bool} selected
	 */
	setSelected : function(selected) {
		this._options.selected = selected;
	},
	/**
	 * Set selectable
	 * 
	 * @param: {Bool} selectable
	 */
	setSelectable : function(selectable) {
		this._options.selectable = selectable;
	},

	getGraphicType : function() {
		return this._graphicType;
	},

	/**
	 * Set Object type
	 * 
	 * @param: {String} type
	 */
	setGraphicType : function(type) {
		this._graphicType = type;
	},

	getAttrs : function() {
		return this._attrs;
	},

	/**
	 * Set multi attrs
	 * 
	 * @param: {Object} configs
	 */
	setAttrs : function(configs) {
		for ( var key in configs)
			this._attrs[key] = configs[key];
	},

	/**
	 * Set single attr by key and value
	 * 
	 * @param: {String} key
	 * @param: {Object} value
	 */
	setAttr : function(key, value) {
		this._attrs[key] = value;
	},

	/**
	 * Set default attrs
	 * 
	 * @param: {Object} configs
	 */
	setAttrsDefault : function(configs) {
		for ( var key in configs)
			this._attrs[key] = configs[key];
	},

	/**
	 * Set multi options
	 * 
	 * @param: {Object} options
	 */
	setOptions : function(options) {
		for ( var key in options)
			this._options[key] = options[key];
	},

	/**
	 * Draw function for override later
	 * 
	 * @param: {Object} configs
	 */
	draw : function(graphic) {
		if(this.isVisible() == true)
		{
			this.drawStart(graphic);
			this.drawShape(graphic);
			this.drawEnd(graphic);
		}
	},
	
	drawBorder: function(graphic){
		this.drawStart(graphic);
		this.drawShape(graphic);
		this.drawEnd(graphic, true);
	},
	
	/**
	 * Setup for draw begin and apply tranform
	 * 
	 */
	drawStart : function(graphic) {
		if (this._options.matrix != null) {
			// Pushes the current state onto the stack.
			graphic.save();
			// apply transform
			this.applyTransform(graphic);
		}
		graphic.beginPath();
	},

	drawEnd : function(graphic, border) {
		if(border != true)
			this.applyStyle(graphic);
		else
			this.applyStyleBorder(graphic);
		
		if (this._options.matrix != null) {
			// restore state such as before applying transform
			graphic.restore();
		}
		graphic.closePath();
	},
	
	applyStyleBorder: function(graphic) {
		if (!!this._attrs.lineCap) {
			graphic.lineCap = this._attrs.lineCap;
		}
		graphic.lineWidth = this.getStrokeWidth() + 1;
		graphic.strokeStyle = "#7000E0";
		graphic.stroke();
		
	},
	
	/**
	 * Set matrix
	 * 
	 * @param: {Array(6)} matrix ([1, 0, 0, 1, 0, 0])
	 */
	
	setMatrix : function(matrix) { 
		this._options.matrix = matrix; 
	},
	
	getMatrix: function(){
		return this._options.matrix;
	},
	

	getStrokeColor : function() {
		return this._options.stroke.color;
	},

	/**
	 * Set pen color
	 * 
	 * @param: {String} color ("black" or "#000")
	 */
	setStrokeColor : function(color) {
		this._options.stroke.color = color;
	},

	/**
	 * Get & set pen width
	 */
	getStrokeWidth : function() {
		return this._options.stroke.width;
	},
	setStrokeWidth : function(width) {
		this._options.stroke.width = width;
	},

	/**
	 * Set fill default for "circle, retangle"
	 */
	setFillDefault : function() {
		this._options.fill = {
			"color" : "none"
		};
	},
	getFillColor : function() {
		return this._options.fill.color;
	},
	setFillColor : function(color) {
		this._options.fill.color = color;
	},
	
	rotateRad: function(rad){
		var centerPoint = this.getCenterPoint();
		this.translate(centerPoint.x, centerPoint.y);
		this.setRotateToMatrix(rad);
		this.translate(-centerPoint.x, -centerPoint.y);
	},
	
	setRotateToMatrix : function(rad) {
		// var m = [1, 0, 0, 1, 0, 0];
		var c = Math.cos(rad);
		var s = Math.sin(rad);
		var m11 = this._options.matrix[0] * c + this._options.matrix[2] * s;
		var m12 = this._options.matrix[1] * c + this._options.matrix[3] * s;
		var m21 = this._options.matrix[0] * -s + this._options.matrix[2] * c;
		var m22 = this._options.matrix[1] * -s + this._options.matrix[3] * c;
		this._options.matrix[0] = m11;
		this._options.matrix[1] = m12;
		this._options.matrix[2] = m21;
		this._options.matrix[3] = m22;
		// return m;
	},
	
	rotateDeg: function(deg){
		var rad = (deg * Math.PI / 180);
		this.rotateRad(rad);
	},
	
	translate: function(x, y)
	{
		this._options.matrix[4] += this._options.matrix[0] * x + this._options.matrix[2] * y;
		this._options.matrix[5] += this._options.matrix[1] * x + this._options.matrix[3] * y;
	},
	
	applyTransform : function(graphic) {
		graphic.transform(this._options.matrix[0], this._options.matrix[1],
				this._options.matrix[2], this._options.matrix[3],
				this._options.matrix[4], this._options.matrix[5]);
	},

	/**
	 * Apply stroke and fill
	 */
	applyStyle: function(graphic) {
		if (!!this._attrs.lineCap) {
			graphic.lineCap = this._attrs.lineCap;
		}
		if (this._options.fill != null) {
			graphic.fillStyle = this.getFillColor();
			graphic.fill();
		}
		graphic.lineWidth = this.getStrokeWidth();
		graphic.strokeStyle = this.getStrokeColor();
		graphic.stroke();
	},
	
	containsPoint: function(x, y){
		var m = Siglaz.Util.invertMatrix(this._options.matrix);
		var p = Siglaz.Util.transformPoint(m, x, y);

		return this.containsPointShape(p.x, p.y);
	}
}

// /////////////////////////////////////////////////////////////////////
// Siglaz.Line
// /////////////////////////////////////////////////////////////////////


Siglaz.Line = function(configs, options) {
	Siglaz.Shape.apply(this);
	
	this.setGraphicType("Line");

	// add default circle attrs
	this.setAttrsDefault({
		points : [], // [{x:1,y:1},{x:2,y:2},...]
		lineCap : "butt" // "butt" or "round" or "square"
	});

	// add custom attrs
	if (undefined !== configs)
		this.setAttrs(configs);
	if (undefined !== options)
		this.setOptions(options);
}


Siglaz.Line.prototype = new Siglaz.Shape();

Siglaz.Line.prototype.constructor = Siglaz.Line;


Siglaz.Line.prototype.drawShape = function(graphic) {
	var lastPos = {};

	graphic.moveTo(this._attrs.points[0].x, this._attrs.points[0].y);
	for ( var n = 1; n < this._attrs.points.length; n++) {
		var x = this._attrs.points[n].x;
		var y = this._attrs.points[n].y;
		// draw normal line
		graphic.lineTo(x, y);
	}

	
}

Siglaz.Line.prototype.containsPointShape = function(x, y){
	var p = this._attrs.points;
	var length = p.length;
	for(var i = 0; i < length-1; i++)
		if(Siglaz.Util.isOnLine(p[i], p[i+1], x, y, this._options.stroke.width))
			return true;
	return false;
}

Siglaz.Line.prototype.getCenterPoint = function(){
	var p = this._attrs.points;
	var top = p[0].y,
		left = p[0].x,
		right = p[0].x,
		bottom = p[0].y;
	for(var i in p)
	{
		left = p[i].x < left ? p[i].x : left;
		top = p[i].y < top ? p[i].y : top;
		right = p[i].x > right ? p[i].x : right;
		bottom = p[i].y > top ? p[i].y : height;
	}
	var width = right - left,
		height = bottom - top;
	var x = left + width/2,
		y = top + height/2;
	return {x: x, y: y};
}

Siglaz.Line.prototype.setPoint = function(points) {
	this._attrs.points = points;
}

Siglaz.Line.prototype.getPoints = function() {
	return this._attrs.points;
}

/**
 * Set LineCap
 * 
 * @param {String}
 *            lineCap: "butt" or "round" or "square"
 */
Siglaz.Line.prototype.setLineCap = function(lineCap) {
	this._attrs.lineCap = lineCap;
}

Siglaz.Line.prototype.getLineCap = function() {
	return this._attrs.lineCap;
}

// /////////////////////////////////////////////////////////////////////
// Siglaz.Circle
// /////////////////////////////////////////////////////////////////////

/**
 * Siglaz Circle
 * 
 * @param {Object}
 *            configs
 * @param {Object}
 *            options
 */
Siglaz.Circle = function(configs, options) {
	Siglaz.Shape.apply(this);
	
	this.setGraphicType("Circle");

	// add default circle attrs
	this.setAttrsDefault({
		x : 1,
		y : 1,
		r : 1
	});
	
	// set brush default
	this.setFillDefault();

	// add custom attrs
	if (undefined !== configs)
		this.setAttrs(configs);
	if (undefined !== options)
		this.setOptions(options);
}

Siglaz.Circle.prototype = new Siglaz.Shape();

Siglaz.Circle.prototype.drawShape = function(graphic) {
	graphic.arc(this._attrs.x, this._attrs.y, this._attrs.r, 0, 2 * Math.PI, false);
}

Siglaz.Circle.prototype.containsPointShape = function(x, y){
	return (x-this._attrs.x)*(x-this._attrs.x) + (y-this._attrs.y)*(y-this._attrs.y) <= (this._attrs.r * this._attrs.r);
}

/**
 * Set Radius
 * 
 * @param {Number}
 *            radius
 */
Siglaz.Circle.prototype.setRadius = function(radius) {
	this._attrs.r = radius;
}

Siglaz.Circle.prototype.getRadius = function() {
	return this._attrs.r;
}

// /////////////////////////////////////////////////////////////////////
// Siglaz.Rectangle
// /////////////////////////////////////////////////////////////////////

/**
 * Siglaz Rectangle
 * 
 * @param {Object}
 *            configs
 * @param {Object}
 *            options
 */


Siglaz.Rectangle = function(configs, options) {
	Siglaz.Shape.apply(this);
	
	this.setGraphicType("Rectangle");

	// add default circle attrs
	this.setAttrsDefault({
		top : 0,
		left : 0,
		width : 0,
		height : 0,
		cornerRadius : 0
	});
	
	// set brush default
	this.setFillDefault();

	// add custom attrs
	if (undefined !== configs)
		this.setAttrs(configs);

	if (undefined !== options)
		this.setOptions(options);	
}


Siglaz.Rectangle.prototype = new Siglaz.Shape();

//Siglaz.Rectangle.prototype.draw = function(graphic) {
	
//}

Siglaz.Rectangle.prototype.drawShape = function(graphic){
	if (this._attrs.cornerRadius === 0) {
		// simple rect - don't bother doing all that complicated maths stuff.
		graphic.rect(this._attrs.left, this._attrs.top, this._attrs.width,
				this._attrs.height);
	} else {
		// arcTo would be nicer, but browser support is patchy (Opera)
		graphic.moveTo(this._attrs.left + this._attrs.cornerRadius,
				this._attrs.top);
		graphic.lineTo(this._attrs.left + this._attrs.width
				- this._attrs.cornerRadius, this._attrs.top);
		graphic.arc(this._attrs.left + this._attrs.width
				- this._attrs.cornerRadius, this._attrs.top
				+ this._attrs.cornerRadius, this._attrs.cornerRadius,
				Math.PI * 3 / 2, 0, false);
		graphic.lineTo(this._attrs.left + this._attrs.width, this._attrs.top
				+ this._attrs.height - this._attrs.cornerRadius);
		graphic.arc(this._attrs.left + this._attrs.width
				- this._attrs.cornerRadius, this._attrs.top
				+ this._attrs.height - this._attrs.cornerRadius,
				this._attrs.cornerRadius, 0, Math.PI / 2, false);
		graphic.lineTo(this._attrs.left + this._attrs.cornerRadius,
				this._attrs.top + this._attrs.height);
		graphic
				.arc(this._attrs.left + this._attrs.cornerRadius,
						this._attrs.top + this._attrs.height
								- this._attrs.cornerRadius,
						this._attrs.cornerRadius, Math.PI / 2, Math.PI, false);
		graphic.lineTo(this._attrs.left, this._attrs.top
				+ this._attrs.cornerRadius);
		graphic.arc(this._attrs.left + this._attrs.cornerRadius,
				this._attrs.top + this._attrs.cornerRadius,
				this._attrs.cornerRadius, Math.PI, Math.PI * 3 / 2, false);
	}
}

Siglaz.Rectangle.prototype.containsPointShape = function(x, y){
	return (x >= this._attrs.left && y >= this._attrs.top &&
			x <= this._attrs.left+this._attrs.width && y <= this._attrs.top + this._attrs.height);
}

Siglaz.Rectangle.prototype.getCenterPoint = function() {
	var x = this._attrs.left + this._attrs.width/2,
		y = this._attrs.top + this._attrs.height/2;
	return {x: x, y: y};
}

/**
 * Set cornerRadius
 * 
 * @param {Number}
 *            radius
 */
Siglaz.Rectangle.prototype.setCornerRadius = function(radius) {
	this._attrs.cornerRadius = radius;
}

Siglaz.Rectangle.prototype.getCornerRadius = function() {
	return this._attrs.cornerRadius;
}

Siglaz.Rectangle.prototype.setWidth = function(width) {
	this._attrs.width = width;
}

Siglaz.Rectangle.prototype.getWidth = function() {
	return this._attrs.width;
}

Siglaz.Rectangle.prototype.setHeight = function(height) {
	this._attrs.height = height;
}

Siglaz.Rectangle.prototype.getHeight = function() {
	return this._attrs.height;
}

/*
 * Siglaz.Rectangle.prototype.getSize = function() { return { width:
 * this._attrs.width, height: this._attrs.height }; },
 */

Siglaz.Rectangle.prototype.setTop = function(top) {
	this._attrs.top = top;
}

Siglaz.Rectangle.prototype.getTop = function() {
	return this._attrs.top;
}

Siglaz.Rectangle.prototype.setLeft = function(left) {
	this._attrs.left = left;
}

Siglaz.Rectangle.prototype.getLeft = function() {
	return this._attrs.left;
}

/*
 * Siglaz.Rectangle.prototype.getOffset = function(){ return { top:
 * this._attrs.top, left: this._attrs.left }; }
 */

// /////////////////////////////////////////////////////////////////////
// Siglaz.Image
// /////////////////////////////////////////////////////////////////////
/**
 * Siglaz Image
 * 
 * @param {Object}
 *            configs
 * @param {Object}
 *            options
 */
Siglaz.Image = function(configs, options) {
	Siglaz.Shape.apply(this);
	
	this.setGraphicType("Image");

	// add default circle attrs
	this.setAttrsDefault({
		src : null,
		top : 0,
		left : 0,
		width : undefined,
		height : undefined,
		crop : {
			top : 0,
			left : 0,
			width : undefined,
			height : undefined
		}
	});

	this.setFillDefault();
	// add custom attrs
	if (undefined !== configs)
		this.setAttrs(configs);
	if (undefined !== options)
		this.setOptions(options);

	
}

Siglaz.Image.prototype = new Siglaz.Shape();

Siglaz.Image.prototype.drawShape = function(graphic){
	graphic.rect(this._attrs.left, this._attrs.top, this._attrs.width, this._attrs.height);
}

Siglaz.Image.prototype.draw = function(graphic) {
	if (this._attrs.src === null)
		return;

	var imageObj = new Image();

	var top = this._attrs.top, 
		left = this._attrs.left, 
		width = this._attrs.width;
		height = this._attrs.height;
		cropWidth = this._attrs.crop.width;
		cropHeight = this._attrs.crop.height;
		cropX = this._attrs.crop.left;
		cropY = this._attrs.crop.top;
		object = this;
	
	imageObj.onload = function() {
		object._attrs.width = width !== undefined ? width : imageObj.naturalWidth;
		object._attrs.height = height !== undefined ? height : imageObj.naturalHeight;

		// if cropping
		object.drawStart(graphic);
		if (cropWidth !== undefined && cropHeight !== undefined) {
			graphic.drawImage(imageObj, cropX, cropY, cropWidth, cropHeight,
					left, top, width, height);
		}
		// no cropping
		else {
			graphic.drawImage(imageObj, left, top, width, height);
		}
		object.drawEnd(graphic);
	}
	imageObj.src = this._attrs.src;
}

Siglaz.Image.prototype.containsPointShape = function(x, y){
	return (x >= this._attrs.left && y >= this._attrs.top &&
			x <= this._attrs.left+this._attrs.width && y <= this._attrs.top + this._attrs.height);
}

Siglaz.Image.prototype.getCenterPoint = function() {
	var x = this._attrs.left + this._attrs.width/2,
		y = this._attrs.top + this._attrs.height/2;
	return {x: x, y: y};
}

Siglaz.Image.prototype.getImageSrc = function() {
	return this._attrs.src;
}

Siglaz.Image.prototype.setImageSrc = function(src) {
	this._attrs.src = src;
}

Siglaz.Image.prototype.setTop = function(top) {
	this._attrs.top = top;
}

Siglaz.Image.prototype.getTop = function() {
	return this._attrs.top;
}

Siglaz.Image.prototype.setLeft = function(left) {
	this._attrs.left = left;
}

Siglaz.Image.prototype.getLeft = function() {
	return this._attrs.left;
}

Siglaz.Image.prototype.setWidth = function(width) {
	this._attrs.width = width;
}

Siglaz.Image.prototype.getWidth = function() {
	return this._attrs.width;
}

Siglaz.Image.prototype.setHeight = function(height) {
	this._attrs.height = height;
}

Siglaz.Image.prototype.getHeight = function() {
	return this._attrs.height;
}

Siglaz.Image.prototype.setCrop = function(crop) {
	this._attrs.crop = crop;
}

Siglaz.Image.prototype.getCrop = function() {
	return this._attrs.crop;
}

// /////////////////////////////////////////////////////////////////////
// Siglaz.Polygon
// /////////////////////////////////////////////////////////////////////
/**
 * Siglaz Polygon
 * 
 * @param {Object}
 *            configs
 * @param {Object}
 *            options
 */

Siglaz.Polygon = function(configs, options) {
	Siglaz.Shape.apply(this);
	
	this.setGraphicType("Polygon");	

	// add default circle attrs
	this.setAttrsDefault({
		points : [], // [{x:1,y:1},{x:2,y:2},...]
		lineCap : "butt" // "butt" or "round" or "square"
	});
	this.setFillDefault();
	// add custom attrs
	if (undefined !== configs)
		this.setAttrs(configs);
	if (undefined !== options)
		this.setOptions(options);	
}

Siglaz.Polygon.prototype = new Siglaz.Shape();

Siglaz.Polygon.prototype.drawShape = function(graphic) {
	//this.drawStart(graphic);

	var lastPos = {};

	graphic.moveTo(this._attrs.points[0].x, this._attrs.points[0].y);
	for ( var n = 1; n < this._attrs.points.length; n++) {
		var x = this._attrs.points[n].x;
		var y = this._attrs.points[n].y;
		// draw normal line
		graphic.lineTo(x, y);
	}

	graphic.lineTo(this._attrs.points[0].x, this._attrs.points[0].y);

}

/*
 * check point in polygon
 */
Siglaz.Polygon.prototype.containsPointShape = function(x, y){
	
	var p = this._attrs.points;
	var length = p.length;
	var i, j, c = 0;
	for (i = 0, j = length-1; i < length; j = i++) {
		if ((p[i].y > y) == (p[j].y > y))
			continue;
		var d = (p[j].y-p[i].y);
		var t = (d >= 0 ? ((x - p[i].x) * d  < (p[j].x-p[i].x) * (y-p[i].y)) : ((x - p[i].x) * d  > (p[j].x-p[i].x) * (y-p[i].y)));
		if (!t)
			continue;
		//var t2 = ((x - p[i].x) * d  < (p[j].x-p[i].x) * (y-p[i].y));
		//if ( ((p[i].y > y) != (p[j].y > y)) &&
				//(x  < (p[j].x-p[i].x) * (y-p[i].y) / (p[j].y-p[i].y) + p[i].x) )
		//		(x - p[i].x) * (p[j].y-p[i].y)  < (p[j].x-p[i].x) * (y-p[i].y))		
		c = t ? !c : c;
	}
	return c;
}

Siglaz.Polygon.prototype.getCenterPoint = function(){
	
	var p = this._attrs.points;
	var top = p[0].y,
		left = p[0].x,
		right = p[0].x,
		bottom = p[0].y;
	for(var i in p)
	{
		left = p[i].x < left ? p[i].x : left;
		top = p[i].y < top ? p[i].y : top;
		right = p[i].x > right ? p[i].x : right;
		bottom = p[i].y > top ? p[i].y : height;
	}
	var width = right - left,
		height = bottom - top;
	var x = left + width/2,
		y = top + height/2;
	return {x: x, y: y};
}

Siglaz.Polygon.prototype.setPoint = function(points) {
	this._attrs.points = points;
}

Siglaz.Polygon.prototype.getPoints = function() {
	return this._attrs.points;
}

/**
 * Set LineCap
 * 
 * @param {String}
 *            lineCap: "butt" or "round" or "square"
 */
Siglaz.Polygon.prototype.setLineCap = function(lineCap) {
	this._attrs.lineCap = lineCap;
}

Siglaz.Polygon.prototype.getLineCap = function() {
	return this._attrs.lineCap;
}
